#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include "cJSON.h"
#include "msg_queue_peer.h"
#include "shmem.h"
struct change
{
    bool LED1;
    bool FAN1;
    bool FIRE1;
    bool DOOR;
};

struct share_mod
{
    bool door;
    float tem;
    float weight;
    float in_pre;
    float air_pre;
    float in_h2;
    float out_h2;
};

struct share_stm
{
    bool GATE;
    bool gs;
    bool LD1;
    bool LD3;
    bool FAN;
    bool FIRE;
    float temp;
    float humi;
    float Vbat;
};

struct share
{
    int id;
    struct share_mod mod;
    struct share_stm stm;
};
struct msg_node nbmsg;
void *pthread(void *arg) // 读取消息队列控制指令,控制modbus slave 线圈
{
    while (1)
    {
        msg_queue_recv("msg", &nbmsg, sizeof(nbmsg), 888, 0);
        printf("消息队列:  key:%d  name:%s  addr:%d  data:%d\n", nbmsg.key, nbmsg.name, nbmsg.addr, nbmsg.data);
    }
}

int main(int argc, char const *argv[])
{
    pthread_t tid1;
    if (pthread_create(&tid1, NULL, pthread, NULL))
    {
        printf("create pthread error\n");
        return -1;
    }
    bool saveld1;
    bool savefan;
    bool savedoor;

    struct change cg;
    cg.LED1=0;
    cg.FAN1=0;
    cg.DOOR=0;
    struct share *s;
    struct shm_param para;
    shm_init(&para, "shm", 1024);           // 共享内存初始化
    s = (struct share *)shm_getaddr(&para); // 获取共享内存地址
    int zhi = s->mod.door;
    int a = 0;
    char buf[1024];
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket create error\n");
        return -1;
    }
    printf("sockfd:%d\n", sockfd);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[1]));
    // addr.sin_port = htons(8888);
    addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    int bd = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
    if (bd < 0)
    {
        perror("bind error\n");
        return -1;
    }

    if (listen(sockfd, 10) < 0)
    {
        perror("listen error\n");
        return -1;
    }
    struct sockaddr_in caddr;
    socklen_t len = sizeof(caddr);
    while (1)
    {
        int accid = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (accid < 0)
        {
            perror("accid create error\n");
            return -1;
        }
        printf("accid:%d\n", accid);
        printf("client ip:%s\n", inet_ntoa(caddr.sin_addr));
        printf("client port:%d\n", ntohs(caddr.sin_port));
        while (1)
        {
            ssize_t rcvid = recv(accid, buf, sizeof(buf), 0);
            if (rcvid < 0)
            {
                perror("recive error\n");
                return -1;
            }
            else if (rcvid == 0)
            {
                printf("client:%s had exit\n", inet_ntoa(caddr.sin_addr));
                break;
            }
            else
            {
                printf("had recive:%d\n", rcvid);
            }

            printf("------牛逼序列化JSON牛逼序列化JSON------\n");
            if (nbmsg.key == 202)
            {
                cg.LED1 = nbmsg.data;
                nbmsg.key = 0;
                printf("LD1LD1LD1LD1LD1\n");
            }
            if (nbmsg.key == 204)
            {
                cg.FAN1 = nbmsg.data;
                nbmsg.key = 0;
                printf("FANFANFANFANFAN\n");
            }
            if (nbmsg.key == 205)
            {
                cg.FIRE1 = nbmsg.data;
                nbmsg.key = 0;
                printf("FIREFIREFIREFIRE\n");
            }
            if (nbmsg.key == 207)
            {
                cg.DOOR = nbmsg.data;
                nbmsg.key = 0;
                printf("DOORDOORDOOR\n");
            }
            cJSON *gen = cJSON_CreateObject();
            cJSON *arr = cJSON_CreateArray();
            cJSON_AddItemToObject(gen, "data1", arr);

            cJSON *item1 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item1, "tem", s->mod.tem);
            cJSON_AddItemToArray(arr, item1);

            cJSON *item2 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item2, "weight", s->mod.weight);
            cJSON_AddItemToArray(arr, item2);

            cJSON *item3 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item3, "in_pre", s->mod.in_pre);
            cJSON_AddItemToArray(arr, item3);

            cJSON *item4 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item4, "air_pre", s->mod.air_pre);
            cJSON_AddItemToArray(arr, item4);

            cJSON *item5 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item5, "in_h2", s->mod.in_h2);
            cJSON_AddItemToArray(arr, item5);

            cJSON *item6 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item6, "out_h2", s->mod.out_h2);
            cJSON_AddItemToArray(arr, item6);

            cJSON *item7 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item7, "ld1", cg.LED1);
            cJSON_AddItemToArray(arr, item7);

            cJSON *item8 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item8, "fan", cg.FAN1);
            cJSON_AddItemToArray(arr, item8);

            cJSON *item9 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item9, "fire", cg.FIRE1);
            cJSON_AddItemToArray(arr, item9);

            cJSON *item10 = cJSON_CreateObject();
            cJSON_AddNumberToObject(item10, "DOORRR", cg.DOOR);
            cJSON_AddItemToArray(arr, item10);

            if (zhi != s->stm.GATE)
            {
                zhi = s->stm.GATE;
                struct msg_node msg = {999, 306, "111", 0, zhi};
                msg_queue_send("msg", &msg, sizeof(msg), 0);
                printf("gate:%d\n", zhi);
            }

            char *val = cJSON_Print(gen);
            printf("%s\n", val);
            send(accid, val, 256, 0);

            //-------------------------------------------------------------------------------------------//
            printf("------牛逼反序列化JSON牛逼反序列化JSON------\n");
            cJSON *root = cJSON_Parse(buf);
            cJSON *item = cJSON_GetObjectItem(root, "Device");
            printf("%s:%s\n", item->string, item->valuestring);

            cJSON *data = cJSON_GetObjectItem(root, "data");

            item = cJSON_GetArrayItem(data, 0);
            item = cJSON_GetObjectItem(item, "temp");
            printf("%s:%s\n", item->string, item->valuestring);
            s->stm.temp = atof(item->valuestring);

            item = cJSON_GetArrayItem(data, 1);
            item = cJSON_GetObjectItem(item, "humi");
            printf("%s:%s\n", item->string, item->valuestring);
            s->stm.humi = atof(item->valuestring);

            item = cJSON_GetArrayItem(data, 2);
            item = cJSON_GetObjectItem(item, "LD1");
            printf("%s:%d\n", item->string, item->valueint);
            s->stm.LD1 = item->valueint;

            item = cJSON_GetArrayItem(data, 3);
            item = cJSON_GetObjectItem(item, "LD3");
            printf("%s:%d\n", item->string, item->valueint);
            s->stm.LD3 = item->valueint;

            item = cJSON_GetArrayItem(data, 4);
            item = cJSON_GetObjectItem(item, "FAN");
            printf("%s:%d\n", item->string, item->valueint);
            s->stm.FAN = item->valueint;

            item = cJSON_GetArrayItem(data, 5);
            item = cJSON_GetObjectItem(item, "FIRE");
            printf("%s:%d\n", item->string, item->valueint);
            s->stm.FIRE = item->valueint;

            item = cJSON_GetArrayItem(data, 6);
            item = cJSON_GetObjectItem(item, "Vbat");
            printf("%s:%s\n", item->string, item->valuestring);
            s->stm.Vbat = atof(item->valuestring);

            item = cJSON_GetArrayItem(data, 7);
            item = cJSON_GetObjectItem(item, "Grating");
            printf("%s:%d\n", item->string, item->valueint);
            s->stm.gs = item->valueint;

            item = cJSON_GetArrayItem(data, 8);
            item = cJSON_GetObjectItem(item, "Gate");
            printf("%s:%d\n", item->string, item->valueint);
            s->stm.GATE = item->valueint;
            // printf("------牛逼结构体牛逼结构体牛逼结构体------\n");
            // printf("Temp:%.1f\n", s->stm.temp);
            // printf("Humi:%.1f\n", s->stm.humi);
            // printf("LD1:%d\n", s->stm.LD1);
            // printf("LD3:%d\n", s->stm.LD3);
            // printf("FAN:%d\n", s->stm.FAN);
            // printf("FIRE:%d\n", s->stm.FIRE);
            // printf("Vbat:%.2f\n", s->stm.Vbat);
            // printf("GS:%d\n", s->stm.gs);
            // printf("Gate:%d\n", s->stm.GATE);
            printf("------牛逼分界线牛逼分界线牛逼分界线------\n");
            memset(buf, 0, sizeof(buf));
        }
        close(accid);
    }
    close(sockfd);
    return 0;
}
